/*
 * StockBean.java
 *
 * Created on 27 March 2007, 13:25
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package usyd.comp5348;

import java.util.ArrayList;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

/**
 *
 * @author Yuezhong Zhang
 */
@Stateless(mappedName="ejb/Stock")
public class StockBean implements StockRemote, StockLocal {
    
    @PersistenceContext
    private EntityManager em;
    
    /** Creates a new instance of StockBean */
    public StockBean() {
    }
    
    public int createItem(StockInfo stock) throws StockException {
        try {
            Stock s = new Stock(stock);
            em.persist(s);
            em.flush();
            stock.setId(s.getId());
            return stock.getId();
        } catch (Exception e) {
            e.printStackTrace();
            throw new StockException("Could not create new stock", e);
        }
    }
    
    public void modifyItem(StockInfo stock) throws StockException {
        try {
            Stock s = new Stock(stock);
            em.merge(s);
            em.flush();
        } catch (Exception e) {
            e.printStackTrace();
            throw new StockException("Could not modify stock", e);
        }
    }
    
    public void deleteItem(int id) throws StockException {
        Stock s;
        try {
            s = em.find(Stock.class, id);
            if (s!=null)
                em.remove(s);
                  em.flush();
        } catch (Exception e) {
            e.printStackTrace();
            throw new StockException("Could not delete stock", e);
        }
        if (s==null)
            throw new StockException("Could not delete stock(" + id + ") - does not exist");
    }
    
    public void sold(int catalogue_id, int quantity, String warehouse) throws StockException {
        Stock s;
        try {
            s = (Stock)em.createNamedQuery("getHoldingByWarehouse").setParameter("warehouse", warehouse).setParameter("catalogueId", catalogue_id).getSingleResult();
            int holding = s.getHolding();
            if (holding<quantity)
                throw new StockException("Attempted to sell more stock from warehouse '" + warehouse + "' for catalogue '"+catalogue_id+"' than is available.");
            holding-=quantity;
            s.setHolding(holding);
            em.merge(s);
            em.flush();
        } catch (Exception e) {
            e.printStackTrace();
            throw new StockException("Could not process sale of stock from warehouse", e);
        }
    }
    
    public int bought(int catalogue_id, int quantity, String warehouse) throws StockException {
        Stock s;
        try {
            s = (Stock)em.createNamedQuery("getHoldingByWarehouse").setParameter("warehouse", warehouse).setParameter("catalogueId", catalogue_id).getSingleResult();
            int holding = s.getHolding();
            holding+=quantity;
            s.setHolding(holding);
            em.merge(s);
            em.flush();
            return holding;
        } catch (Exception e) {
            e.printStackTrace();
            throw new StockException("Could not process addition of stock to warehouse", e);
        }
    }
    
    public StockInfo getItemById(int id) throws StockException {
        try {
            Stock s = em.find(Stock.class, id);
            if (s==null)
                return null;
            return s.getStockInfo();
        } catch (Exception e) {
            e.printStackTrace();
            throw new StockException("Could not retrieve Stock by Id", e);
        }
    }
    
    public List<StockInfo> getItemByWarehouse(String warehouse) throws StockException {
        try {
            List<Stock> stocks = em.createNamedQuery("getItemByWarehouse").setParameter("warehouse", warehouse).getResultList();
            if (stocks==null)
                return null;
            List<StockInfo> sinfo = new ArrayList<StockInfo>();
            for (Stock s: stocks)
                sinfo.add(s.getStockInfo());
            return sinfo;
        } catch (Exception e) {
            e.printStackTrace();
            throw new StockException("Could not retrieve Stock by warehouse", e);
        }
    }
    
    public int getHoldingByWarehouse(int catalogue_id, String warehouse) throws StockException {
        try {
            Stock s = (Stock)em.createNamedQuery("getHoldingByWarehouse").setParameter("warehouse", warehouse).setParameter("catalogueId", catalogue_id).getSingleResult();
            if (s==null)
                return 0;
            return s.getHolding();
        } catch (Exception e) {
            e.printStackTrace();
            throw new StockException("Could not retrieve Stock by warehouse and catalogue_id", e);
        }
    }
}
